/////////////////////////////////////////////////////////////////////////////
// Name:        ax_resource.h
// Purpose:     Accessibility classes: AxResource
// Author:      Julian Smart
// Modified by:
// Created:     2009-03-20
// RCS-ID:
// Copyright:   (c) Julian Smart
// Licence:     New BSD License
/////////////////////////////////////////////////////////////////////////////

#ifndef _AX_RESOURCE_H_
#define _AX_RESOURCE_H_

/*
 * Includes
 */

#include "wx/dynarray.h"

#include "ax/ax_property.h"
#include "ax/ax_document.h"

class AxResource;
class wxDataStreamHelper;

WX_DEFINE_ARRAY_PTR(AxResource*, AxResourceArray);

/*
 * Common resource property names
 */

#define axPROPERTY_TITLE            wxT("Title")
#define axPROPERTY_LONG_TITLE       wxT("Long title")
#define axPROPERTY_AUTHOR           wxT("Author")
#define axPROPERTY_CONTRIBUTORS     wxT("Contributors")
#define axPROPERTY_PUBLISHER        wxT("Publisher")
#define axPROPERTY_CREATION_DATE    wxT("Creation date")
#define axPROPERTY_LANGUAGE         wxT("Language")
#define axPROPERTY_IDENTIFIER       wxT("Identifier")
#define axPROPERTY_SUBJECT          wxT("Subject")
#define axPROPERTY_GENRE            wxT("Genre")
#define axPROPERTY_DESCRIPTION      wxT("Description")
#define axPROPERTY_FORMAT           wxT("Format")
#define axPROPERTY_NOTES            wxT("Notes")
#define axPROPERTY_SOURCE           wxT("Source")
#define axPROPERTY_SOURCE_URL       wxT("Source URL")
#define axPROPERTY_COVERAGE         wxT("Coverage")
#define axPROPERTY_RIGHTS           wxT("Rights")
#define axPROPERTY_PROVIDER_URL     wxT("Provider URL")
#define axPROPERTY_FILENAME         wxT("Filename")
#define axPROPERTY_RESOURCE_TYPE    wxT("Resource type")
#define axPROPERTY_RESOURCE_STATUS  wxT("Resource status")

#define axPROPERTY_RELEVANT_FROM_DATE   wxT("Relevant from date")
#define axPROPERTY_RELEVANT_TO_DATE     wxT("Relevant to date")
#define axPROPERTY_ACTIVATE_DATE        wxT("Activate date")

/*
 * Common resource property values
 */

// Resource types

#define axPROPERTY_RESOURCE_TYPE_EBOOK          wxT("Ebook")
#define axPROPERTY_RESOURCE_TYPE_PRINT_BOOK     wxT("Print book")
#define axPROPERTY_RESOURCE_TYPE_AUDIO_BOOK     wxT("Audio book")
#define axPROPERTY_RESOURCE_TYPE_AUDIO_ALBUM    wxT("Audio album")
#define axPROPERTY_RESOURCE_TYPE_AUDIO_TRACK    wxT("Audio track")
#define axPROPERTY_RESOURCE_TYPE_VIDEO          wxT("Video")
#define axPROPERTY_RESOURCE_TYPE_DOCUMENT       wxT("Document")
#define axPROPERTY_RESOURCE_TYPE_UTILITY        wxT("Utility")
#define axPROPERTY_RESOURCE_TYPE_SERVICE        wxT("Service")
#define axPROPERTY_RESOURCE_TYPE_REMINDER       wxT("Reminder")
#define axPROPERTY_RESOURCE_TYPE_UNKNOWN        wxT("Unknown")

// Resource statuses

#define axPROPERTY_RESOURCE_STATUS_OWNED        wxT("Owned")
#define axPROPERTY_RESOURCE_STATUS_WANTED       wxT("Wanted")
#define axPROPERTY_RESOURCE_STATUS_UNKNOWN      wxT("Unknown")

/**
    @class AxResource
    
    A resource can represent a tool, document, file, web site, etc.

    @category{ax_resource}
 */

class AxResource: public AxDocument
{
    DECLARE_DYNAMIC_CLASS( AxResource )

public:
// Constructors

    AxResource(const AxResource& resource) { Init(); Copy(resource); }
    AxResource() { Init(); }
    ~AxResource();

// Operations

    void Init();

    /// Copy the basic resource information.
    void Copy(const AxResource& resource);

    /// Assignment operator
    void operator=(const AxResource& resource) { Copy(resource); }

    /// Test equality for the basic resource information
    bool Eq(const AxResource& resource) const;

    /// Clone - derived classes must implement this function.
    virtual AxDocument* Clone() const { return new AxResource(*this); }

    /// Read the data for this resource. By default, this simply reads
    /// the properties and children. Override this function to read other data.
    virtual bool Read(wxDataStreamHelper& helper);

    /// Read public properties, always the first part of the record
    virtual bool ReadProperties(wxDataStreamHelper& helper);

    /// Write the data for this resource. By default, this simply writes
    /// the properties and children. Override this function to write other data.
    virtual bool Write(wxDataStreamHelper& helper);

    /// Write public properties, always the first part of the record
    virtual bool WriteProperties(wxDataStreamHelper& helper);

    /// Read children
    virtual bool ReadChildren(wxDataStreamHelper& helper);

    /// Write children
    virtual bool WriteChildren(wxDataStreamHelper& helper);

    /// Set filename
    virtual void SetFilename(const wxString& filename) { SetProperty(axPROPERTY_FILENAME, filename); }

    /// Get filename
    virtual wxString GetFilename() const { return GetPropertyString(axPROPERTY_FILENAME); }

    /// Get long description. Override to return a more complete description.
    virtual wxString GetLongDescription() const { return GetPropertyString(axPROPERTY_DESCRIPTION); }

    /// Get short description. Override to return a more complete description.
    virtual wxString GetShortDescription() const { return GetPropertyString(axPROPERTY_DESCRIPTION); }

    /// Get properties
    AxProperties& GetProperties() { return m_properties; }

    /// Set a property
    virtual void SetProperty(const AxProperty& property);
    virtual void SetProperty(const wxString& name, const wxString& value);
    virtual void SetProperty(const wxString& name, const wxChar* value) { SetProperty(name, wxString(value)); }
    virtual void SetProperty(const wxString& name, const wxString& value, const wxArrayString& choices);
    virtual void SetProperty(const wxString& name, long value);
    virtual void SetProperty(const wxString& name, int value);
    virtual void SetProperty(const wxString& name, bool value);
    virtual void SetProperty(const wxVariant& value);

    /// Get a property
    virtual AxProperty GetProperty(const wxString& name) const;

    /// Get a property value variant
    virtual wxVariant GetPropertyValue(const wxString& name) const;

    /// Get a string property value
    virtual wxString GetPropertyString(const wxString& name) const;
    virtual wxString GetPropertyString(const wxChar* name) const { return GetPropertyString(wxString(name)); }

    /// Get a long property value
    virtual long GetPropertyLong(const wxString& name) const;

    /// Get a double property value
    virtual double GetPropertyDouble(const wxString& name) const;

    /// Get a bool property value
    virtual long GetPropertyBool(const wxString& name) const;

    /// Does this property exist?
    virtual bool HasProperty(const wxString& name) const;

    /// Get current properties - doesn't necessarily mean they're all supported
    virtual wxArrayString EnumerateProperties() const;

    /// Get property count
    virtual int GetPropertyCount() const { return m_properties.GetCount(); }

    /// Get property
    virtual AxProperty GetProperty(size_t i) const;
    virtual AxProperty* GetPropertyPtr(size_t i) const { return m_properties.GetNth(i); }

    /// Get resource children, if any
    AxResourceArray& GetChildren() { return m_children; }
    const AxResourceArray& GetChildren() const { return m_children; }

    /// Clear children
    void ClearChildren();
    void Clear() { ClearChildren(); }

    /// Add child
    bool AddChild(AxResource* resource);

    /// Remove child
    bool RemoveChild(AxResource* resource);

    /// Get child count
    size_t GetCount() const { return m_children.GetCount(); }

    /// Get child
    AxResource* GetChild(size_t i) const { return m_children[i]; }

    /// Get/set local file flag
    bool GetLocalFile() const { return m_localFile; }
    void SetLocalFile(bool mod) { m_localFile = mod; }

    /// Find by filename (look at this object, and children).
    virtual AxResource* FindByFilename(const wxString& filename) const;

protected:

    AxProperties            m_properties;
    AxResourceArray         m_children;

    bool                    m_localFile;
};

#endif
    // _AX_RESOURCE_H_
